﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.IO;
using System.IO.Compression;
using System.Drawing;
using System.Windows.Forms;
using Newtonsoft.Json;
using System.Threading;
using AutoBuyWinform.entity;
using HtmlAgilityPack;
using AutoBuyWinform.utils;
using System.Collections;

namespace AutoBuyWinform
{
    public class Operations
    {
        //Logs logs;
        CheckCodeForm checkCodeForm;
        LinkedList<Thread> threadContainer = new LinkedList<Thread>();

        public LinkedList<Thread> getThreadContainer()
        {
            return this.threadContainer;
        }

        //用于存储获取newCheckCode信息的类
        public struct CheckCode
        {
            public string J_checkCodeUrl { get; set; }
            public string isCheckCode { get; set; }
            public string encrypterString { get; set; }
            public string sid { get; set; }
            public string gmtCreate { get; set; }
            public string checkCodeIds { get; set; }
            public string checkCode { get; set; }
        }

        public Operations()
        {
            //this.logs = logs;
            checkCodeForm = new CheckCodeForm();
        }

        

        //获取验证码
        public string GetVeriCode(string loginUrl, string captchaUrl, CookieContainer cc, out CookieCollection ccReturned)
        {
            //string page = operations.GetPage(loginUrl, GetCookieContainerCopy(cc), out ccReturned);
            string page = Util.GetPage(loginUrl, cc, out ccReturned);
            if (ccReturned!=null)
                cc.Add(ccReturned);

            ////show cookie
            //StringBuilder sb = new StringBuilder();
            //foreach (Cookie cookieValue in ccReturned)
            //{
            //    sb.AppendLine("Cookie: " + cookieValue.ToString());
            //}
            //MessageBox.Show(sb.ToString());

            //MessageBox.Show(page);
            Bitmap image = new Bitmap(Util.GetCheckCodeImageStream(captchaUrl, cc, out ccReturned));
            if (ccReturned != null)
                cc.Add(ccReturned);
            checkCodeForm.checkCodePic.Image = image;
            checkCodeForm.ShowDialog();
            return checkCodeForm.txtCheckCode.Text;

        }

        //用于登录的方法
        public bool Login(string loginUrl, string userName, string password, string veriCode, CookieContainer ccEntered, out CookieCollection ccReturned)
        {
            HttpWebRequest request;
            HttpWebResponse response;


            request = (HttpWebRequest)HttpWebRequest.Create(loginUrl+"/account/api/login/");
            request.CookieContainer = new CookieContainer();

            string data = "username=" + userName + "&password=" + password + "&captcha=" + veriCode;

            byte[] postData = Encoding.UTF8.GetBytes(data);

            request.Method = "POST";
            request.ProtocolVersion = HttpVersion.Version11;

            //request.Connection = "keep-alive";

            request.UserAgent = "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.43 Safari/537.31";
            request.ContentType = "application/x-www-form-urlencoded; charset=UTF-8";
            request.ContentLength = postData.Length;
            request.Referer = loginUrl;
            //request.KeepAlive = true;
            var sp = request.ServicePoint;
            var prop = sp.GetType().GetProperty("HttpBehaviour", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
            prop.SetValue(sp, (byte)0, null);

            request.Accept = "application/json, text/javascript, */*; q=0.01";

            //request.Headers.Add("Connection", "keep-alive");

            request.Headers.Add("Cache-Control", "max-age=0");
            request.Headers.Add("Accept-Encoding", "gzip,deflate,sdch");
            request.Headers.Add("Accept-Language", "zh-CN,zh;q=0.8");
            request.Headers.Add("Accept-Charset", "GBK,utf-8;q=0.7,*;q=0.3");
            request.Headers.Add("Origin", loginUrl);
            request.Headers.Add("X-Requested-With", "XMLHttpRequest");

            request.CookieContainer = ccEntered;

            Stream st = request.GetRequestStream();
            st.Write(postData, 0, postData.Length);
            st.Close();

            request.AllowAutoRedirect = false;

            response = (HttpWebResponse)request.GetResponse();
            ccReturned = response.Cookies;


            Stream st2 = response.GetResponseStream();

            if (response.ContentEncoding.ToLower().Contains("gzip"))
            {
                st = new GZipStream(st2, CompressionMode.Decompress, true);
            }

            string htmlText;

            StreamReader stReader = new StreamReader(st2, Encoding.Default);
            htmlText = stReader.ReadToEnd();

            stReader.Close();
            st2.Close();

            response.Close();

            RespStatus rs = JsonConvert.DeserializeObject<RespStatus>(htmlText);

            if (rs.status == 1)
            {
                MessageBox.Show("登陆成功");
            }
            else
            {
                if (rs.status == 0)
                {
                    MessageBox.Show("用户名或密码错误");
                }
                else if (rs.status == -3)
                {
                    MessageBox.Show("验证码错误");
                }
                else
                {
                    MessageBox.Show(rs.message);
                }
                
            }

            return rs.status == 1 ? true : false;
        }


        public bool Logout(string logoutUrl,CookieContainer ccEntered, out CookieCollection ccReturned)
        {
            HttpWebRequest request = Util.createRequest(logoutUrl, "", Form1.webUrl, Form1.webUrl, "GET", Constants.ACCEPT_TYPE_PLAIN, ccEntered);
            Util.getResponse(request, out ccReturned);
            return false;
        }
        

        //通过URL打开页面，目前没用
        public string ToUrl(string toUrl,CookieContainer cc)
        {
            HttpWebRequest request;
            HttpWebResponse response;
            request = WebRequest.Create(toUrl) as HttpWebRequest;
            request.Method = "GET";
            request.KeepAlive = false;
            request.CookieContainer = cc;

            // 提交请求数据
            response = request.GetResponse() as HttpWebResponse;
            using (System.IO.Stream responseStream = response.GetResponseStream())
            {
                using (System.IO.StreamReader reader = new System.IO.StreamReader(responseStream, Encoding.GetEncoding("utf-8")))
                {
                    string srcString = reader.ReadToEnd(); // 接收返回的页面
                    return srcString;
                }
            }

        }

        public List<String> getGoodsUrls(string s)
        {
            //MessageBox.Show(listPage);
            ////解析议价窗口
            //// 使用預設編碼讀入 HTML
            //HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
            //doc.LoadHtml(listPage);
            //// 裝載Chat body
            //HtmlAgilityPack.HtmlDocument bodyContext = new HtmlAgilityPack.HtmlDocument();

            //bodyContext.LoadHtml(doc.DocumentNode.SelectSingleNode("/html[1]/body[1]/div[1]/div[1]/div[1]").InnerHtml);

            ////获取参数
            //String sycsStr = chatBodyContext.DocumentNode.SelectSingleNode("./div[1]/div[2]/span[1]").InnerText;
            return null;
        }

        //生成商品对象
        public Product GetProduct(string productPage)
        {
            int btnIdx = productPage.IndexOf("javascript:addToCart");
            if (btnIdx == -1)
            {
                //MessageBox.Show("请确认商品购买页面URL是否正确，无法找到\"加入购物车\"按钮。");
                return null;
            }

            int startIdx = productPage.IndexOf("(", btnIdx);
            int endIdx = productPage.IndexOf(";", btnIdx);
            string paramStr = productPage.Substring(startIdx + 1, endIdx - startIdx - 2);

            string[] param = paramStr.Split(new string[] { ", " }, StringSplitOptions.RemoveEmptyEntries);
            Product product = new Product();

            if (param.Length == 6)
            {
                product.packId = Int64.Parse(param[0].Trim());
                product.weight = Double.Parse(param[1].Trim());
                product.price = param[2].Trim().Replace("'", "");
                product.productTypeId = param[3].Trim().Replace("'", "");
                product.prodTypeDesc = param[4].Trim().Replace("'", "");
                product.providerCode = param[5].Trim().Replace("'", "");
            }
            else
            {
                string[] subParam = param[0].Split(new string[] { ",'" }, StringSplitOptions.RemoveEmptyEntries);
                product.packId = Int64.Parse(subParam[0].Trim());
                product.weight = Double.Parse(param[1].Trim().Replace("'", ""));
                product.price = subParam[1].Trim().Replace("'", "");
                //product.productTypeId = param[3].Trim().Replace("'","");
                product.prodTypeDesc = param[2].Trim().Replace("'", "");
                product.providerCode = param[3].Trim().Replace("'", "");
            }


            product.yj[0] = Form1.yj1;
            product.yj[1] = Form1.yj2;
            product.yj[2] = Form1.yj3;

            return product;
        }

        //public Product GetProduct(string productPage)
        //{
        //    int btnIdx = productPage.IndexOf("javascript:addToCart");
        //    if (btnIdx == -1)
        //    {
        //        //MessageBox.Show("请确认商品购买页面URL是否正确，无法找到\"加入购物车\"按钮。");
        //        return null;
        //    }

        //    int startIdx = productPage.IndexOf("(", btnIdx);
        //    int endIdx = productPage.IndexOf(";", btnIdx);
        //    string paramStr = productPage.Substring(startIdx + 1, endIdx - startIdx - 2);

        //    string[] param = paramStr.Split(new string[]{", "}, StringSplitOptions.RemoveEmptyEntries);
        //    string[] subParam = param[0].Split(new string[] { ",'" }, StringSplitOptions.RemoveEmptyEntries);
        //    Product product = new Product();
        //    product.packId = Int64.Parse(subParam[0].Trim());
        //    product.weight = Double.Parse(param[1].Trim().Replace("'",""));
        //    product.price = subParam[1].Trim().Replace("'","");
        //    //product.productTypeId = param[3].Trim().Replace("'","");
        //    product.prodTypeDesc = param[2].Trim().Replace("'","");
        //    product.providerCode = param[3].Trim().Replace("'","");

        //    product.yj[0] = Form1.yj1;
        //    product.yj[1] = Form1.yj2;
        //    product.yj[2] = Form1.yj3;

        //    return product;
        //}

        //加入购物车
        public bool AddToCart(Product product, CookieContainer ccEntered)
        {

            LogForm logFrom = new LogForm(product, ccEntered);
            logFrom.Text = product.prodTypeDesc + " 日志窗口";
            logFrom.Visible = true;
            logFrom.startBuy();

            //Thread t = new Thread(() =>
            //{
            //    bool success = false;
            //    PostGoodsToCart pc = new PostGoodsToCart(product, ccEntered);
            //    success = pc.doPost();
            //    if (!success)
            //    {
            //        MessageBox.Show("加入购物车失败");
            //        return;
            //    }

            //    success = pc.createOrder();
            //    if (!success)
            //    {
            //        MessageBox.Show("生成订单失败");
            //        return;
            //    }

            //    MessageBox.Show("抢购成功！");

            //    Application.Run();
            //});
            //t.SetApartmentState(ApartmentState.MTA);
            //t.Start();
            //threadContainer.AddLast(t);

            return false;
        }

        /// <summary>
        /// 获取该搜索结果页面的产品
        /// </summary>
        /// <param name="consition"></param>
        /// <param name="pageNo"></param>
        /// <param name="productConditions"></param>
        /// <param name="ccEntered"></param>
        /// <returns></returns>
        private HtmlNodeCollection getSearchResultPageProds(string consition, WebForm wf, int pageNo)
        {
            CookieCollection ccReturned = new CookieCollection();

            String listUrl = Form1.searchUrl + (pageNo + 1) + "/" + "?mymall=1&time=" + DateTime.Now.TimeOfDay.Ticks.ToString() + consition;
            //String page = Util.GetPage(listUrl, ccEntered, out ccReturned);
            String page = wf.getPageByClickPageNo(pageNo+1);

            if (page == "")
            {
                return null;
            }

            //解析议价窗口
            // 使用預設編碼讀入 HTML
            HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
            doc.LoadHtml(page);
            // 裝載Chat body
            HtmlAgilityPack.HtmlDocument chatBodyContext = new HtmlAgilityPack.HtmlDocument();

            chatBodyContext.LoadHtml(doc.DocumentNode.SelectSingleNode("/body").InnerHtml);

            HtmlNodeCollection divs = chatBodyContext.DocumentNode.SelectNodes("child::div");

            HtmlNode div = HtmlAgilityPackUtil.findFirstOneHasAttr(divs, "ng-include");

            chatBodyContext.LoadHtml(div.SelectSingleNode("/div/div/div/div[@class='selresult_list_area']/div").InnerHtml);

            HtmlNodeCollection prods = chatBodyContext.DocumentNode.SelectNodes("child::div");

            return prods;

        }

        //扫描商品列表
        public string searchProducts(LogForm searchLogForm, ProductConditions productConditions, ArrayList buyedPackid, WebForm wf,CookieContainer ccEntered)
        {
            CookieCollection ccReturned = new CookieCollection();
            ArrayList cs = productConditions.getConditionStrings();
            foreach (String c in cs)
            {
                String listUrl = Form1.searchUrl + "?mymall=1&time=" + (DateTime.Now.TimeOfDay.Ticks/1000).ToString() + c;
                //String page = Util.GetPage(listUrl, ccEntered, out ccReturned);
                //WebForm wf = new WebForm();
                String page = wf.getPage(listUrl);

                //searchLogForm.Invoke(new Action(() =>
                //    {
                //        searchLogForm.setMsg(listUrl);
                //        searchLogForm.setMsg((page != "").ToString());
                //    }));

                if (page == "")
                {
                    continue;
                }

                // 使用預設編碼讀入 HTML
                HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
                doc.LoadHtml(page);
                // 裝載Chat body
                HtmlAgilityPack.HtmlDocument chatBodyContext = new HtmlAgilityPack.HtmlDocument();

                chatBodyContext.LoadHtml(doc.DocumentNode.SelectSingleNode("/body").InnerHtml);

                HtmlNodeCollection prods;
                HtmlNodeCollection divs = chatBodyContext.DocumentNode.SelectNodes("child::div");
                string pageCountStr = null;
                int pageCount = 1;

                HtmlNode div = HtmlAgilityPackUtil.findFirstOneHasAttr(divs, "ng-include");

                //读取总页数
                if (div != null)
                {
                    //HtmlNode a = div.SelectSingleNode("./table/tr[last()]/td/div/a[@class='total_pages']");
                    HtmlNode a = div.SelectSingleNode("./div/div[2]/span/span[2]/strong");
                    if(a!=null)
                        pageCountStr = a.InnerText;
                }
                else
                {
                    return listUrl + "\n页面结构不匹配，请查询结果页面";
                }


                if (pageCountStr != null && pageCountStr != "")
                {
                    pageCount = Int32.Parse(pageCountStr);
                }

                for (int i = 0; i < pageCount; ++i)
                {
                    prods = getSearchResultPageProds(c, wf, i);
                    

                    if (prods != null)
                    {
                        foreach (HtmlNode prod in prods)
                        {
                            ProductCondition condition = productConditions.getProductCondition(cs.IndexOf(c));

                            //if (condition.pm.Equals())

                            string prodUrl = prod.SelectSingleNode("./div[1]/a[1]").GetAttributeValue("href",null);
                            string prodPage = Util.GetPage(prodUrl,ccEntered,out ccReturned);
                            Product product = GetProduct(prodPage);

                            if (product == null)
                            {
                                continue;
                            }

                            if (product.prodTypeDesc.Contains(condition.pm)
                                && prod.SelectSingleNode("./ul[1]/li[1]/a[1]").InnerText.Trim().Contains(condition.ph)
                                && condition.jg_max >= Double.Parse(product.price))
                            {
                                searchLogForm.Invoke(new Action(() =>
                                {
                                    if (!buyedPackid.Contains(product.packId))
                                    {
                                        //prod.SelectSingleNode("./td[2]/#text[2]");
                                        //foreach (HtmlNode n in prod.SelectSingleNode("./td[2]").ChildNodes)
                                        //{
                                        //    MessageBox.Show(n.XPath.ToString()+":"+ n.InnerText);
                                        //}
                                        //     ("./td[2]/a").Clear();
                                        product.ph = prod.SelectSingleNode("./ul[1]/li[1]/a[1]").InnerText.Trim();
                                        //product.ph = condition.ph;

                                        product.hd = prod.SelectSingleNode("./ul[1]/li[2]").InnerText.Split('*')[0];
                                        string prodMs = product.prodTypeDesc + " " + product.ph + " " + product.hd + " " + product.price + "元";

                                        searchLogForm.setMsg("开始抢拍：" + prodMs);
                                        buyedPackid.Add(product.packId);
                                        LogForm buyLogForm = new LogForm(product, ccEntered);
                                        buyLogForm.Text = prodMs + " 日志窗口";
                                        buyLogForm.Visible = true;
                                        buyLogForm.startBuy();
                                    }
                                }));


                            }


                        }
                    }
                    
                }

            }
            return null;
        }

        
    }
}
